package cn.edu.tju.core.security.service;


import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.security.repository.AuthorityRepository;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.edu.tju.core.security.SecurityUtils;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.model.Person;
import cn.edu.tju.core.security.repository.UserRepository;
import cn.edu.tju.core.security.rest.dto.RegisterDto;
import org.springframework.web.bind.annotation.PostMapping;
import cn.edu.tju.core.security.repository.PersonRepository;
import cn.edu.tju.core.security.repository.AuthorityRepository;


import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.repository.AuthorityRepository;
import cn.edu.tju.core.security.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.edu.tju.core.model.Person;
import cn.edu.tju.core.security.repository.PersonRepository;

import cn.edu.tju.elm.repository.BusinessApplicationRepository;
import cn.edu.tju.elm.repository.BusinessRepository;
import cn.edu.tju.elm.repository.OrderRepository;


import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class UserService {
   @Autowired
   private UserRepository userRepository;
   @Autowired
   private AuthorityRepository authorityRepository;
   @Autowired
   private PersonRepository personRepository;
   @Autowired
   private BusinessApplicationRepository businessApplicationRepository;
   @Autowired
   private BusinessRepository businessRepository;
   @Autowired
   private OrderRepository orderRepository;

   public UserService(UserRepository userRepository) {
      this.userRepository = userRepository;
   }

   @Transactional(readOnly = true)
   public Optional<User> getUserWithAuthorities() {
      return SecurityUtils.getCurrentUsername().flatMap(userRepository::findOneWithAuthoritiesByUsername);
   }

   public User addUser(User user) {
      return userRepository.save(user);
   }

   public User updateUser(User user) {
      return userRepository.save(user);
   }

   public Boolean isEmptyUserTable() {
      List<User> userList = userRepository.findAll();
      return userList.isEmpty();
   }

    public User getUserById(Long userId) {
       return userRepository.findById(userId).orElse(null);
    }

   public void addAuthorityToUser(String username, String authorityName) {
      User user = userRepository.findOneByUsername(username)
              .orElseThrow(() -> new RuntimeException("用户不存在"));

      Authority authority = authorityRepository.findById(authorityName)
              .orElseThrow(() -> new RuntimeException("权限不存在"));

      // 检查是否已经拥有该权限
      boolean alreadyHasAuthority = user.getAuthorities().stream()
              .anyMatch(auth -> auth.getName().equals(authorityName));

      if (!alreadyHasAuthority) {
         user.getAuthorities().add(authority);
         userRepository.save(user);
      }
   }

   //获取当前登录用户的个人信息
   @Transactional(readOnly = true)
   public Person getCurrentPerson() {
      User currentUser = getUserWithAuthorities()
              .orElseThrow(() -> new RuntimeException("用户未登录"));
      return personRepository.findById(currentUser.getId())
              .orElseThrow(() -> new RuntimeException("个人信息不存在"));
   }

   //更新当前登录用户的个人信息
   public Person updateCurrentPerson(Person updatedPerson) {
      User currentUser = getUserWithAuthorities()
              .orElseThrow(() -> new RuntimeException("用户未登录"));

      Person existingPerson = personRepository.findById(currentUser.getId())
              .orElseThrow(() -> new RuntimeException("个人信息不存在"));

      // 只更新允许修改的字段，防止修改用户名等敏感信息
      if (updatedPerson.getFirstName() != null) {
         existingPerson.setFirstName(updatedPerson.getFirstName().trim());
      }
      if (updatedPerson.getLastName() != null) {
         existingPerson.setLastName(updatedPerson.getLastName().trim());
      }
      if (updatedPerson.getEmail() != null) {
         existingPerson.setEmail(updatedPerson.getEmail().trim().toLowerCase());
      }
      if (updatedPerson.getPhone() != null) {
         existingPerson.setPhone(updatedPerson.getPhone().trim());
      }
      if (updatedPerson.getGender() != null) {
         existingPerson.setGender(updatedPerson.getGender());
      }
      if (updatedPerson.getPhoto() != null) {
         existingPerson.setPhoto(updatedPerson.getPhoto());
      }

      // 设置更新信息
      existingPerson.setUpdateTime(LocalDateTime.now());
      existingPerson.setUpdater(currentUser.getId());

      return personRepository.save(existingPerson);
   }


   //获取所有用户列表（管理员）
   @Transactional(readOnly = true)
   public List<User> findAllUsers() {
      return userRepository.findAll();
   }

   //根据ID删除用户（软删除）
   @Transactional
   public boolean deleteUserById(Long id) {
      Optional<User> userOptional = userRepository.findById(id);
      if (userOptional.isPresent()) {
         User user = userOptional.get();
         user.setDeleted(true);
         user.setUpdateTime(java.time.LocalDateTime.now());

         // 设置更新者为当前用户
         Optional<User> currentUser = getUserWithAuthorities();
         if (currentUser.isPresent()) {
            user.setUpdater(currentUser.get().getId());
         }

         userRepository.save(user);
         return true;
      }
      return false;
   }

   //根据用户名查找用户
   @Transactional(readOnly = true)
   public Optional<User> findByUsername(String username) {
      return userRepository.findOneWithAuthoritiesByUsername(username);
   }

   //检查用户是否有特定权限
   public boolean hasAuthority(User user, String authorityName) {
      return user.getAuthorities().stream()
              .anyMatch(authority -> authority.getName().equals(authorityName));
   }

   //获取统计数据
   @Transactional(readOnly = true)
   public DashboardStats getDashboardStats() {
      DashboardStats stats = new DashboardStats();

      // 用户总数
      stats.setTotalUsers(userRepository.countByDeletedFalse());

      // 待审核申请数（状态为0）
      stats.setPendingApplications(businessApplicationRepository.countByStatus(0));

      // 店铺总数
      stats.setTotalBusinesses(businessRepository.countByDeletedFalse());

      // 订单总数
      stats.setTotalOrders(orderRepository.countByDeletedFalse());

      return stats;
   }

   // 内部类：统计数据DTO
   public static class DashboardStats {
      private long totalUsers;
      private long pendingApplications;
      private long totalBusinesses;
      private long totalOrders;

      // Getters and Setters
      public long getTotalUsers() {
         return totalUsers;
      }

      public void setTotalUsers(long totalUsers) {
         this.totalUsers = totalUsers;
      }

      public long getPendingApplications() {
         return pendingApplications;
      }

      public void setPendingApplications(long pendingApplications) {
         this.pendingApplications = pendingApplications;
      }

      public long getTotalBusinesses() {
         return totalBusinesses;
      }

      public void setTotalBusinesses(long totalBusinesses) {
         this.totalBusinesses = totalBusinesses;
      }

      public long getTotalOrders() {
         return totalOrders;
      }

      public void setTotalOrders(long totalOrders) {
         this.totalOrders = totalOrders;
      }
   }

}
